home *** CD-ROM | disk | FTP | other *** search
- // DirectDraw サンプルゲーム
- // PingPong.cpp
-
- #include "stdafx.h"
- #include "pingpong.h"
-
- #define APPNAME "PingPong"
-
- IDirectDraw *lpDD=NULL; // DirectDrawオブジェクト
- IDirectDrawSurface *lpDDPrimary=NULL; // プライマリサーフェス
- IDirectDrawSurface *lpDDBack=NULL; // バックサーフェス
- IDirectDrawSurface *lpDDPad=NULL; // オフスクリーンサーフェイス
- IDirectDrawSurface *lpDDBall=NULL; // "
- IDirectDrawSurface *lpDDBG=NULL; // "
-
- HINSTANCE hAppInst;
- LRESULT CALLBACK WndProc(HWND, UINT, UINT, LONG);
-
- BOOL bActive = FALSE;
- DWORD lastCount;
- // ボール
- struct ball{
- float X,Y; // 座標
- float XAdd,YAdd; // 移動量
- }Ball;
- // パドル
- struct pad{
- int X; // 描画座標
- int XAdd; // 移動量
- }Pad;
- // 反発力テーブル
- float PadDir[16][2]={
- -1.99036944f,-0.19603428f, //左
- -1.71388071f,-0.92603428f,
- -1.71388071f,-0.98056933f,
- -1.76384258f,-0.94279349f,
- -1.54602087f,-1.26878655f,
- -1.26878655f,-1.54602087f,
- -0.94279349f,-1.76384258f,
- -0.58056933f,-1.91388071f, //中央
- -0.19603428f,-1.99036944f, //
- 0.19603428f,-1.99036944f,
- 0.58056933f,-1.91388071f,
- 0.94279349f,-1.76384258f,
- 1.26878655f,-1.54602087f,
- 1.54602087f,-1.26878655f,
- 1.76384258f,-0.94279349f,
- 1.71388071f,-0.98056933f, //右
- };
-
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- WNDCLASS wc;
- HWND hWnd;
- MSG msg;
-
- wc.style=CS_HREDRAW|CS_VREDRAW;
- wc.lpfnWndProc=WndProc;
- wc.cbClsExtra=0;
- wc.cbWndExtra=0;
- wc.hInstance=hInstance;
- wc.hIcon=LoadIcon(hInstance, IDI_APPLICATION);
- wc.hCursor=LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground=(HBRUSH)GetStockBrush(BLACK_BRUSH);
- wc.lpszMenuName=0;
- wc.lpszClassName=APPNAME;
-
- RegisterClass(&wc);
-
- hAppInst=hInstance;
- // ウィンドウクラスの登録
- hWnd=CreateWindowEx(0, APPNAME, APPNAME, WS_POPUP, 0, 0,
- GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
- NULL, NULL, hInstance, NULL);
-
- if(!hWnd) return FALSE;
-
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
-
- // アプリケーションの初期化
- if(!InitDDraw(hWnd)) return FALSE;
-
- // 初期化終了
- bActive = TRUE;
-
- // メッセージポンプ
- while(TRUE){
- if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){
- if(!GetMessage(&msg, NULL, 0, 0)){
- return msg.wParam;
- }
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- if(bActive) Render();
- }
- return 0;
- }
-
- long FAR PASCAL WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch(message){
-
- case WM_ACTIVATEAPP:
- bActive=(BOOL)wParam;
- if(bActive && lpDD)
- ResumeScreen();
- break;
- case WM_CREATE:
- break;
- case WM_SETCURSOR:
- SetCursor(NULL);
- return TRUE;
-
- case WM_KEYDOWN:
- switch(wParam){
- case VK_ESCAPE:
- DestroyWindow(hWnd);
- break;
- }
- return TRUE;
-
- case WM_DESTROY:
- bActive=FALSE;
- ReleaseObjects();
- PostQuitMessage(0);
- break;
- }
- return DefWindowProc(hWnd,message,wParam,lParam);
- }
-
- // オブジェクトの開放
- void ReleaseObjects()
- {
- RELEASE(lpDDBG);
- RELEASE(lpDDBall);
- RELEASE(lpDDPad);
- RELEASE(lpDDBack);
- RELEASE(lpDDPrimary);
- RELEASE(lpDD);
- }
-
- // DirectDraw初期化エラー処理
- BOOL InitDDError(HWND hWnd)
- {
- ReleaseObjects();
- MessageBox(hWnd, "Initialize Error", "DirectDraw Initialize", MB_OK|MB_ICONHAND);
- return FALSE;
- }
-
- // サーフェスの修復
- BOOL ResumeScreen()
- {
- DDCOLORKEY ddck;
-
- lpDDPrimary->Restore();
- lpDDBack->Restore();
- lpDDPad->Restore();
- lpDDBall->Restore();
- lpDDBG->Restore();
-
- HDC hDCDest;
- lpDDPad->GetDC(&hDCDest); // スプライトサーフェスのDCを取得
- // リソースからビットマップをロード
- HBITMAP hBmp=(HBITMAP)LoadImage(NULL, "Pad.Bmp", IMAGE_BITMAP,0, 0,
- LR_LOADFROMFILE|LR_CREATEDIBSECTION);
- HDC hDCSrc=CreateCompatibleDC(NULL); // メモリデバイスコンテキストを作成
-
- // スプライトサーフェスへコピーする
- SelectObject(hDCSrc, hBmp); // ビットマップを選択
- BitBlt(hDCDest, 0, 0, 64, 16, hDCSrc, 0, 0, SRCCOPY); // コピー
- DeleteObject(hBmp); // ビットマップを復帰
- lpDDPad->ReleaseDC(hDCDest); // スプライトサーフェスのDCを開放
-
- lpDDBall->GetDC(&hDCDest);
- hBmp=(HBITMAP)LoadImage(NULL, "Ball.Bmp", IMAGE_BITMAP,0, 0,
- LR_LOADFROMFILE|LR_CREATEDIBSECTION );
- SelectObject(hDCSrc, hBmp);
- BitBlt(hDCDest, 0, 0, 16, 16, hDCSrc, 0, 0, SRCCOPY);
- DeleteObject(hBmp);
- lpDDBall->ReleaseDC(hDCDest);
-
- lpDDBG->GetDC(&hDCDest);
- hBmp=(HBITMAP)LoadImage( NULL, "BG.Bmp", IMAGE_BITMAP,0, 0,
- LR_LOADFROMFILE|LR_CREATEDIBSECTION );
-
- SelectObject(hDCSrc, hBmp);
- BitBlt(hDCDest, 0, 0, 640, 480, hDCSrc, 0, 0, SRCCOPY);
- DeleteObject(hBmp);
- lpDDBG->ReleaseDC(hDCDest);
-
- DeleteDC(hDCSrc); // メモリデバイスコンテキストを開放
-
- // カラーキーを設定
- ddck.dwColorSpaceLowValue = 0; // 黒を指定
- ddck.dwColorSpaceHighValue = 0;
- lpDDPad->SetColorKey(DDCKEY_SRCBLT, &ddck);
- lpDDBall->SetColorKey(DDCKEY_SRCBLT, &ddck);
-
- return TRUE;
- }
-
- void Render()
- {
- int x;
- RECT rect;
-
- rect.left=rect.top=0;
- rect.right=640;
- rect.bottom = 480;
- // 背景の描画
- lpDDBack->BltFast(0, 0, lpDDBG, &rect, DDBLTFAST_WAIT|DDBLTFAST_NOCOLORKEY);
-
- Pad.XAdd=0;
-
- // キー入力
- if(GetAsyncKeyState(VK_RIGHT)) Pad.XAdd=10;
- if(GetAsyncKeyState(VK_LEFT)) Pad.XAdd=-10;
-
- if(Pad.X>525-42) Pad.X=525-42;
- if(Pad.X<95) Pad.X=95;
-
- rect.right=64;
- rect.bottom=16;
- // パドルの描画
- lpDDBack->BltFast(Pad.X, 416, lpDDPad,&rect,
- DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
-
- Pad.X+=Pad.XAdd; // パドルの移動
-
- // パドルとボールの当り判定
- if((int)Ball.Y>416-16 && (int)Ball.Y<416){
- if((int)Ball.X>Pad.X-8 && (int)Ball.X<Pad.X+64-8){
- // パドルのどこにボールが当たったのか?
- x=((int)(Ball.X+8-Pad.X)>>2)&0x0f;
- // 反発力テーブルを参照して,ボールの移動量を決定
- Ball.XAdd=PadDir[x][0]*2;
- Ball.YAdd=PadDir[x][1]*2;
- }
- }
-
- // ボールの移動&描画
- Ball.X+=Ball.XAdd;
- Ball.Y+=Ball.YAdd;
- rect.right=16;
- rect.bottom = 16;
- lpDDBack->BltFast((int)Ball.X, (int)Ball.Y, lpDDBall, &rect,
- DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
-
- // ボールの移動範囲をチェック
- if(Ball.X<95){
- Ball.X=100;
- Ball.XAdd=-Ball.XAdd;
- }
- if(Ball.X>530){
- Ball.X=530;
- Ball.XAdd=-Ball.XAdd;
- }
- if(Ball.Y<0){
- Ball.Y=0;
- Ball.YAdd=-Ball.YAdd;
- }
- // ミスをしたか?
- if(Ball.Y>480-32)
- InitGame();
-
- // ゲームウェイト
- DWORD thisCount;
- do thisCount=GetTickCount();
- while(thisCount-lastCount<1000/120);
-
- // フリッピング
- lpDDPrimary->Flip(NULL,DDFLIP_WAIT);
-
- lastCount=thisCount;
- }
-
- // DirectDrawの初期化
- BOOL InitDDraw(HWND hWnd)
- {
- // DirectDrawオブジェクトの作成
- if(DirectDrawCreate(NULL,&lpDD,NULL)!=DD_OK) return FALSE;
-
- // 協調レベルの設定
- lpDD->SetCooperativeLevel(hWnd,
- DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN);
-
- // 画面モードの設定
- lpDD->SetDisplayMode(640, 480, 16);
-
- // プライマリサーフェイスの初期化
- DDSURFACEDESC ddsd;
- DDSCAPS ddscaps;
-
- ZeroMemory(&ddsd, sizeof(ddsd));
- ZeroMemory(&ddscaps, sizeof(ddscaps));
-
- ddsd.dwSize=sizeof(ddsd);
- ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
- ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE|
- DDSCAPS_FLIP|DDSCAPS_COMPLEX;
- ddsd.dwBackBufferCount=1;
-
- lpDD->CreateSurface(&ddsd, &lpDDPrimary, NULL);
-
- ddscaps.dwCaps=DDSCAPS_BACKBUFFER;
- lpDDPrimary->GetAttachedSurface(&ddscaps, &lpDDBack);
-
- // オフスクリーンサーフェイスの初期化
- ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth=64;
- ddsd.dwHeight=24;
- lpDD->CreateSurface(&ddsd, &lpDDPad, NULL);
-
- ddsd.dwWidth=16;
- ddsd.dwHeight=16;
- lpDD->CreateSurface(&ddsd, &lpDDBall, NULL);
-
- ddsd.dwWidth=640;
- ddsd.dwHeight=480;
- lpDD->CreateSurface(&ddsd, &lpDDBG, NULL);
-
- // プライマリとバックサーフェイスのクリア
- DDBLTFX ddbltfx;
- ZeroMemory(&ddbltfx, sizeof(DDBLTFX));
- ddbltfx.dwSize=sizeof(DDBLTFX);
- lpDDPrimary->Blt(NULL, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &ddbltfx);
- lpDDBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &ddbltfx);
-
- if(!ResumeScreen()){
- ReleaseObjects();
- MessageBox(hWnd, "Surface Restore Error", "Surface Initialize", MB_OK|MB_ICONHAND);
- return FALSE;
- }
- InitGame();
-
- return TRUE;
- }
- // ゲーム初期化
- void InitGame()
- {
- // ゲーム情報の初期化
- Pad.X=290;
- Ball.X=Ball.Y=50;
- Ball.XAdd=Ball.YAdd=2;
- }
-